/**
 * 通用工具函数集合
 * 提供DOM操作、表单验证、数据处理等常用功能
 */

/**
 * DOM操作工具类
 */
export const DOMUtils = {
  /**
   * 根据选择器获取元素
   * @param {string} selector - CSS选择器
   * @param {HTMLElement} parent - 父元素，默认为document
   * @returns {HTMLElement|null} 匹配的元素或null
   */
  $(selector, parent = document) {
    return parent.querySelector(selector);
  },

  /**
   * 根据选择器获取多个元素
   * @param {string} selector - CSS选择器
   * @param {HTMLElement} parent - 父元素，默认为document
   * @returns {NodeList} 匹配的元素列表
   */
  $$(selector, parent = document) {
    return parent.querySelectorAll(selector);
  },

  /**
   * 创建新元素
   * @param {string} tagName - 标签名
   * @param {Object} attributes - 属性对象
   * @param {Array<HTMLElement|string>} children - 子元素数组
   * @returns {HTMLElement} 创建的元素
   */
  createElement(tagName, attributes = {}, children = []) {
    const element = document.createElement(tagName);
    
    // 设置属性
    Object.entries(attributes).forEach(([key, value]) => {
      if (key === 'className') {
        element.className = value;
      } else if (key === 'style' && typeof value === 'object') {
        Object.entries(value).forEach(([cssKey, cssValue]) => {
          element.style[cssKey] = cssValue;
        });
      } else if (key.startsWith('on') && typeof value === 'function') {
        element.addEventListener(key.slice(2).toLowerCase(), value);
      } else {
        element.setAttribute(key, value);
      }
    });
    
    // 添加子元素
    children.forEach(child => {
      if (typeof child === 'string') {
        element.appendChild(document.createTextNode(child));
      } else if (child instanceof Node) {
        element.appendChild(child);
      }
    });
    
    return element;
  },

  /**
   * 切换元素的类名
   * @param {HTMLElement} element - 目标元素
   * @param {string} className - 要切换的类名
   * @returns {boolean} 当前是否包含该类名
   */
  toggleClass(element, className) {
    element.classList.toggle(className);
    return element.classList.contains(className);
  },

  /**
   * 检查元素是否包含某个类名
   * @param {HTMLElement} element - 目标元素
   * @param {string} className - 要检查的类名
   * @returns {boolean} 是否包含该类名
   */
  hasClass(element, className) {
    return element.classList.contains(className);
  },

  /**
   * 为元素添加类名
   * @param {HTMLElement} element - 目标元素
   * @param {...string} classNames - 要添加的类名
   */
  addClass(element, ...classNames) {
    element.classList.add(...classNames);
  },

  /**
   * 移除元素的类名
   * @param {HTMLElement} element - 目标元素
   * @param {...string} classNames - 要移除的类名
   */
  removeClass(element, ...classNames) {
    element.classList.remove(...classNames);
  },

  /**
   * 平滑滚动到指定元素
   * @param {HTMLElement|string} target - 目标元素或选择器
   * @param {Object} options - 滚动选项
   */
  scrollToElement(target, options = {}) {
    const element = typeof target === 'string' ? this.$(target) : target;
    if (!element) return;
    
    const defaultOptions = {
      behavior: 'smooth',
      block: 'center',
      inline: 'nearest'
    };
    
    const mergedOptions = { ...defaultOptions, ...options };
    element.scrollIntoView(mergedOptions);
  },

  /**
   * 获取元素相对于视口的位置
   * @param {HTMLElement} element - 目标元素
   * @returns {Object} 位置信息
   */
  getElementPosition(element) {
    const rect = element.getBoundingClientRect();
    return {
      top: rect.top,
      left: rect.left,
      right: rect.right,
      bottom: rect.bottom,
      width: rect.width,
      height: rect.height
    };
  }
};

/**
 * 表单验证工具类
 */
export const ValidationUtils = {
  /**
   * 验证电子邮件格式
   * @param {string} email - 要验证的电子邮件
   * @returns {boolean} 是否有效
   */
  isValidEmail(email) {
    const pattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return pattern.test(email);
  },

  /**
   * 验证手机号码格式（中国）
   * @param {string} phone - 要验证的手机号码
   * @returns {boolean} 是否有效
   */
  isValidPhone(phone) {
    const pattern = /^1[3-9]\d{9}$/;
    return pattern.test(phone);
  },

  /**
   * 验证密码强度
   * @param {string} password - 要验证的密码
   * @returns {Object} 密码强度信息
   */
  checkPasswordStrength(password) {
    let strength = 0;
    let feedback = '';
    
    if (password.length >= 8) strength++;
    if (/[A-Z]/.test(password)) strength++;
    if (/[a-z]/.test(password)) strength++;
    if (/\d/.test(password)) strength++;
    if (/[^A-Za-z0-9]/.test(password)) strength++;
    
    switch (strength) {
      case 0:
      case 1:
        feedback = '弱';
        break;
      case 2:
      case 3:
        feedback = '中';
        break;
      case 4:
      case 5:
        feedback = '强';
        break;
    }
    
    return {
      strength,
      feedback
    };
  },

  /**
   * 验证URL格式
   * @param {string} url - 要验证的URL
   * @returns {boolean} 是否有效
   */
  isValidURL(url) {
    try {
      new URL(url);
      return true;
    } catch (e) {
      return false;
    }
  },

  /**
   * 验证是否为数字
   * @param {string|number} value - 要验证的值
   * @returns {boolean} 是否为数字
   */
  isNumber(value) {
    return !isNaN(value) && isFinite(value);
  },

  /**
   * 验证是否为空
   * @param {any} value - 要验证的值
   * @returns {boolean} 是否为空
   */
  isEmpty(value) {
    return value === undefined || value === null || value === '';
  },

  /**
   * 验证字符串长度范围
   * @param {string} value - 要验证的字符串
   * @param {number} min - 最小长度
   * @param {number} max - 最大长度
   * @returns {boolean} 是否在范围内
   */
  isLengthBetween(value, min, max) {
    return value.length >= min && value.length <= max;
  }
};

/**
 * 数据处理工具类
 */
export const DataUtils = {
  /**
   * 深拷贝对象
   * @param {any} obj - 要拷贝的对象
   * @returns {any} 拷贝后的对象
   */
  deepClone(obj) {
    if (obj === null || typeof obj !== 'object') return obj;
    
    if (obj instanceof Date) return new Date(obj.getTime());
    if (obj instanceof Array) return obj.map(item => this.deepClone(item));
    
    const clonedObj = {};
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        clonedObj[key] = this.deepClone(obj[key]);
      }
    }
    
    return clonedObj;
  },

  /**
   * 防抖函数
   * @param {Function} func - 要防抖的函数
   * @param {number} delay - 延迟时间（毫秒）
   * @returns {Function} 防抖后的函数
   */
  debounce(func, delay) {
    let timeoutId;
    return function (...args) {
      clearTimeout(timeoutId);
      timeoutId = setTimeout(() => func.apply(this, args), delay);
    };
  },

  /**
   * 节流函数
   * @param {Function} func - 要节流的函数
   * @param {number} limit - 时间限制（毫秒）
   * @returns {Function} 节流后的函数
   */
  throttle(func, limit) {
    let inThrottle;
    return function (...args) {
      if (!inThrottle) {
        func.apply(this, args);
        inThrottle = true;
        setTimeout(() => inThrottle = false, limit);
      }
    };
  },

  /**
   * 格式化数字为千分位
   * @param {number|string} num - 要格式化的数字
   * @returns {string} 格式化后的字符串
   */
  formatNumber(num) {
    return Number(num).toLocaleString('zh-CN');
  },

  /**
   * 格式化金额
   * @param {number|string} amount - 金额
   * @param {number} decimals - 小数位数
   * @returns {string} 格式化后的金额
   */
  formatCurrency(amount, decimals = 2) {
    const num = Number(amount);
    return `¥${num.toFixed(decimals).replace(/\B(?=(\d{3})+(?!\d))/g, ',')}`;
  },

  /**
   * 生成随机数
   * @param {number} min - 最小值
   * @param {number} max - 最大值
   * @returns {number} 随机数
   */
  getRandomNumber(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  },

  /**
   * 生成随机字符串
   * @param {number} length - 字符串长度
   * @returns {string} 随机字符串
   */
  getRandomString(length = 8) {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let result = '';
    for (let i = 0; i < length; i++) {
      result += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return result;
  }
};

/**
 * 浏览器存储工具类
 */
export const StorageUtils = {
  /**
   * 设置本地存储
   * @param {string} key - 存储键
   * @param {any} value - 存储值
   * @param {number} expiry - 过期时间（毫秒）
   */
  set(key, value, expiry = null) {
    try {
      const data = {
        value,
        timestamp: Date.now(),
        expiry: expiry ? Date.now() + expiry : null
      };
      localStorage.setItem(key, JSON.stringify(data));
    } catch (error) {
      console.error('Error setting localStorage:', error);
    }
  },

  /**
   * 获取本地存储
   * @param {string} key - 存储键
   * @returns {any} 存储值
   */
  get(key) {
    try {
      const item = localStorage.getItem(key);
      if (!item) return null;
      
      const data = JSON.parse(item);
      
      // 检查是否过期
      if (data.expiry && Date.now() > data.expiry) {
        localStorage.removeItem(key);
        return null;
      }
      
      return data.value;
    } catch (error) {
      console.error('Error getting localStorage:', error);
      return null;
    }
  },

  /**
   * 移除本地存储
   * @param {string} key - 存储键
   */
  remove(key) {
    try {
      localStorage.removeItem(key);
    } catch (error) {
      console.error('Error removing localStorage:', error);
    }
  },

  /**
   * 清空所有本地存储
   */
  clear() {
    try {
      localStorage.clear();
    } catch (error) {
      console.error('Error clearing localStorage:', error);
    }
  },

  /**
   * 设置会话存储
   * @param {string} key - 存储键
   * @param {any} value - 存储值
   */
  setSession(key, value) {
    try {
      sessionStorage.setItem(key, JSON.stringify(value));
    } catch (error) {
      console.error('Error setting sessionStorage:', error);
    }
  },

  /**
   * 获取会话存储
   * @param {string} key - 存储键
   * @returns {any} 存储值
   */
  getSession(key) {
    try {
      const item = sessionStorage.getItem(key);
      return item ? JSON.parse(item) : null;
    } catch (error) {
      console.error('Error getting sessionStorage:', error);
      return null;
    }
  },

  /**
   * 移除会话存储
   * @param {string} key - 存储键
   */
  removeSession(key) {
    try {
      sessionStorage.removeItem(key);
    } catch (error) {
      console.error('Error removing sessionStorage:', error);
    }
  },

  /**
   * 清空所有会话存储
   */
  clearSession() {
    try {
      sessionStorage.clear();
    } catch (error) {
      console.error('Error clearing sessionStorage:', error);
    }
  }
};

/**
 * 网络请求工具类
 */
export const NetworkUtils = {
  /**
   * 检查网络连接状态
   * @returns {Promise<boolean>} 是否在线
   */
  async checkConnection() {
    try {
      const response = await fetch('https://www.google.com/favicon.ico', {
        method: 'HEAD',
        cache: 'no-cache'
      });
      return response.ok;
    } catch (error) {
      return navigator.onLine;
    }
  },

  /**
   * 判断是否为移动设备
   * @returns {boolean} 是否为移动设备
   */
  isMobile() {
    return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
  },

  /**
   * 判断是否为触摸屏设备
   * @returns {boolean} 是否为触摸屏设备
   */
  isTouchDevice() {
    return 'ontouchstart' in window || navigator.maxTouchPoints > 0;
  },

  /**
   * 获取浏览器信息
   * @returns {Object} 浏览器信息
   */
  getBrowserInfo() {
    const userAgent = navigator.userAgent;
    let browser = 'Unknown';
    let version = 'Unknown';
    
    if (userAgent.match(/Chrome\//)) {
      browser = 'Chrome';
      version = userAgent.match(/Chrome\/(\d+)/)[1];
    } else if (userAgent.match(/Firefox\//)) {
      browser = 'Firefox';
      version = userAgent.match(/Firefox\/(\d+)/)[1];
    } else if (userAgent.match(/Safari\//) && !userAgent.match(/Chrome\//)) {
      browser = 'Safari';
      version = userAgent.match(/Version\/(\d+)/)[1];
    } else if (userAgent.match(/MSIE|Trident\//)) {
      browser = 'Internet Explorer';
      version = userAgent.match(/MSIE (\d+)|rv:(\d+)/)[1] || userAgent.match(/MSIE (\d+)|rv:(\d+)/)[2];
    } else if (userAgent.match(/Edge\//)) {
      browser = 'Edge';
      version = userAgent.match(/Edge\/(\d+)/)[1];
    }
    
    return {
      browser,
      version,
      userAgent
    };
  },

  /**
   * 获取操作系统信息
   * @returns {string} 操作系统信息
   */
  getOSInfo() {
    const userAgent = navigator.userAgent;
    if (userAgent.match(/Windows/)) return 'Windows';
    if (userAgent.match(/Macintosh/)) return 'macOS';
    if (userAgent.match(/Linux/)) return 'Linux';
    if (userAgent.match(/iPhone|iPad|iPod/)) return 'iOS';
    if (userAgent.match(/Android/)) return 'Android';
    return 'Unknown';
  }
};

/**
 * 动画工具类
 */
export const AnimationUtils = {
  /**
   * 元素淡入效果
   * @param {HTMLElement} element - 目标元素
   * @param {number} duration - 动画持续时间（毫秒）
   * @returns {Promise<void>} 动画完成的Promise
   */
  async fadeIn(element, duration = 300) {
    return new Promise((resolve) => {
      element.style.opacity = '0';
      element.style.transition = `opacity ${duration}ms ease`;
      element.style.display = 'block';
      
      // 强制重排
      element.offsetHeight;
      
      element.style.opacity = '1';
      
      setTimeout(() => {
        resolve();
      }, duration);
    });
  },

  /**
   * 元素淡出效果
   * @param {HTMLElement} element - 目标元素
   * @param {number} duration - 动画持续时间（毫秒）
   * @returns {Promise<void>} 动画完成的Promise
   */
  async fadeOut(element, duration = 300) {
    return new Promise((resolve) => {
      element.style.opacity = '1';
      element.style.transition = `opacity ${duration}ms ease`;
      
      element.style.opacity = '0';
      
      setTimeout(() => {
        element.style.display = 'none';
        resolve();
      }, duration);
    });
  },

  /**
   * 元素滑动进入效果
   * @param {HTMLElement} element - 目标元素
   * @param {Object} options - 动画选项
   * @returns {Promise<void>} 动画完成的Promise
   */
  async slideIn(element, options = {}) {
    const {
      direction = 'top',
      distance = '20px',
      duration = 300
    } = options;
    
    return new Promise((resolve) => {
      element.style.opacity = '0';
      element.style.transition = `all ${duration}ms ease`;
      element.style.display = 'block';
      
      // 设置初始位置
      if (direction === 'top' || direction === 'bottom') {
        element.style.transform = `translateY(${direction === 'top' ? '-' : ''}${distance})`;
      } else if (direction === 'left' || direction === 'right') {
        element.style.transform = `translateX(${direction === 'left' ? '-' : ''}${distance})`;
      }
      
      // 强制重排
      element.offsetHeight;
      
      // 动画到最终位置
      element.style.opacity = '1';
      element.style.transform = 'translate(0, 0)';
      
      setTimeout(() => {
        resolve();
      }, duration);
    });
  },

  /**
   * 元素缩放进入效果
   * @param {HTMLElement} element - 目标元素
   * @param {number} duration - 动画持续时间（毫秒）
   * @returns {Promise<void>} 动画完成的Promise
   */
  async scaleIn(element, duration = 300) {
    return new Promise((resolve) => {
      element.style.opacity = '0';
      element.style.transform = 'scale(0.8)';
      element.style.transition = `all ${duration}ms ease`;
      element.style.display = 'block';
      
      // 强制重排
      element.offsetHeight;
      
      element.style.opacity = '1';
      element.style.transform = 'scale(1)';
      
      setTimeout(() => {
        resolve();
      }, duration);
    });
  }
};

/**
 * 导出所有工具类
 */
export default {
  DOMUtils,
  ValidationUtils,
  DataUtils,
  StorageUtils,
  NetworkUtils,
  AnimationUtils
};